Skip to content

test: align CI guards with current runtime behavior - #5344

Merged
huangruiteng merged 2 commits into
loopx-project:mainfrom
Duang777:codex/fix-ci-generated-hook-guards
Sep 30, 2026
Merged

huangruiteng merged 2 commits into
loopx-project:mainfrom
Duang777:codex/fix-ci-generated-hook-guards

Conversation

@Duang777

@Duang777 Duang777 commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • account for both verified generated Turn modules in the independent twin guard
  • validate the turn-start capability dispatch while preserving checks for unchanged fields
  • publish the Host descendant marker through an atomic rename so process termination cannot expose a partial write
  • extract the signed test-only baseline repairs from perf(authority): copy journal JSON without repeated primitive allocation #5251 without copying its performance changes

These changes repair the current main failures blocking #5340. They do not change production runtime behavior. The original author is preserved on both commits.

Validation

  • python -m pytest -q tests/architecture/test_turn_contract_generation.py tests/control_plane/test_prompt_upgrade_hook.py (38 passed)
  • Node 22: tests/control_plane_ts/host_process.test.ts (9 passed)
  • Node 22: repeated the Host process test 10 times without failure
  • ruff check tests/architecture/test_turn_contract_generation.py tests/control_plane/test_prompt_upgrade_hook.py
  • git diff --check origin/main...HEAD

@Duang777 Duang777 changed the title test: align CI guards with generated digest and hook dispatch test: align CI guards with current runtime behavior Sep 30, 2026
@Duang777

Copy link
Copy Markdown
Collaborator Author

This baseline repair also unblocks #5338. On #5338 exact head 73f937907, both prompt-hook parameters and the generated-pair assertion reproduced unchanged on immutable base 996bcc027; the separate leader_exit failure passed on rerun. The fixes remain isolated here rather than being copied into either feature PR.

@Duang777

Copy link
Copy Markdown
Collaborator Author

CI dependency update: dashboard-acceptance failed outside this PR's diff with the current main execution-chip baseline:

Error: Execution chip is not a compact hairline row: 28px tall

Exact job: https://github.com/loopx-project/loopx/actions/runs/36692413558/job/109813982376

The independent one-line fix is #5345. It restores the desktop button to the existing 26px contract, leaves the mobile 44px touch target unchanged, and passes the packaged execution-chip browser scenario on main@7e60e6999. #5344 does not modify the dashboard files involved in that failure.

cocolord
cocolord previously approved these changes Sep 30, 2026

@cocolord cocolord left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

动机

这个 PR 修复的是当前主干的测试基线,而不是通过改生产逻辑来追求绿灯。主干已经有两个经过源码重建验证的 Python/TypeScript generated twin,也已经会在待升级提示存在时投影 turn_start_capability_hook_dispatch;旧测试仍分别假定数量为 1、该字段不存在。另一个真实 CI 失败来自 Host 子进程在被终止时恰好进行原地写入,读取方先看到 27、随后看到空串,从而把半写文件误判成子进程仍在运行。

改动思路

改动保留现有生产 owner,只修正三个测试观察点:generated-twin 用当前两个 source-verified pair 作为显式 ratchet,并继续用 mutation 证明新增 authored twin 会消耗独立模块预算;prompt-upgrade 在比较其余决策字段不变之前,先验证 typed dispatch 的 hook/capability 身份和投影内容;Host fixture 先写同目录 staged 文件,再用原子 rename 发布完整计数,使“返回后 marker 是否继续变化”仍是有效的存活判据。

具体改动

  • test_turn_contract_generation.py 将已验证 generated twin 数从 1 更新为 2,原有超预算负例保持不变。
  • test_prompt_upgrade_hook.py 对 baseline 无 dispatch、pending 恰有一条 read、heartbeat.prompt_upgrade / automation-prompt-upgrade 身份以及与公开 hint 的字段一致性作显式断言;只有这个已验证字段被排除在其余决策字段的等值比较之外。
  • host_process.test.ts 把 counter 从原地覆盖改为 marker.next 写完后 renameSync,不修改被测 Host 实现、超时或清理语义。

关键代码讲解

test_new_independent_twin_cannot_hide_behind_generated_pair 仍会注入足量的 authored twin 并要求预算检查失败,因此不是简单放宽计数;prompt-upgrade 用 dispatch 内的 hook_id、capability_id 和完整 hint 字段锁住 typed route;Host 的 publish 只有在 staged 内容完整时才替换可观察 marker,存活子进程仍会在下一次完整 tick 改变它。

对主干的风险

whole-diff 没有生产代码、公共 API、持久状态或权限变化。主要风险是测试修复掩盖真实回归:这里 generated-twin 的 mutation 负例仍在,prompt 测试先校验新增字段再做窄范围排除,Host oracle 只屏蔽终止瞬间的半写状态,并未屏蔽返回后的完整写入。更新后的 immutable base 上同一 Python 命令稳定失败 3 项,新 exact head 38/38 通过;Host 新 exact head 完整复跑 10 次共 90 项通过,来源 CI 的 leader_exit 失败明确记录为空串与 27 的差异。Ruff、diff hygiene、DCO、4 个 Python shard、3 个 TypeScript shard、mutation、平台与集成检查均通过。

当前 merge readiness 仍有独立 hold:chat-bundle-browser 与 dashboard-acceptance 都在 execution-chip 的 28px hairline 断言失败;immutable base ba1e92d860027d2cf209d869249dcf61e6a11651 的对应两项以相同签名失败,且本 PR 不改 Dashboard/UI。checks、pytest、merge-gate 只是传播这两个结果。因此按 policy-12 不要求本 PR 修复无关主干问题,但合并前仍需由维护者处理或解除这些红项。

#5339 含有重叠的 Python 基线修复,但它是更大的 installer PR;本 PR 独立落地后应由 #5339 在 rebase 时消解重复。最新提交只是签署合并当前 main,贡献 diff 与前一 head 完全一致;审批仅绑定 fbd56efe262e75d6dc0ac3f00224addf58ea6d7f,不替代合并前的 freshness/merge-readiness 检查。

我的整体评价

这是一个有明确 before/after 收益的窄测试修复:它解除会持续阻塞其他 PR 的三项确定性基线假红,并修复一个有历史 CI 反例的观察竞态,同时把三个观察点保留为可失败的具体契约,没有新增一次性 smoke、框架或生产兼容层。对长周期交付是正向的,对终端用户行为保持不变;相关 future-facing pass 不需要额外抽象。未发现由本 PR 引入的阻断项,批准该 exact head,但不授予合并权限;上面的 UI 红项仍是独立 merge-readiness hold。

English verdict: APPROVE - exact head fbd56efe262e75d6dc0ac3f00224addf58ea6d7f restores three reproduced baseline assertions and removes a demonstrated partial-write test-oracle race without production changes; focused base/head checks, ten Host-suite repetitions, lint, DCO, and every changed-code CI shard passed. Two unrelated UI jobs fail identically on the immutable base and remain a separate merge-readiness hold.

@Duang777

Copy link
Copy Markdown
Collaborator Author

Exact-head run 36692413558 completed with all four Python test shards, all three TypeScript shards, kernel static checks, Windows PowerShell, Stage 2C, and coverage passing. The aggregate pytest log records SHARDS_RESULT=success; its failure is inherited from the same run's two execution-chip UI jobs.

The independent UI repair #5345 is now green on exact head c33543eaae57f33e28c82f0c85be27216bbe785b with 20 passing checks, including dashboard-acceptance, chat-bundle-browser, Frontstage Pages, Release Artifacts, and merge-gate. No UI change is being copied into this PR.

After #5345 lands, this branch can be synchronized once and rerun without mixing the two baseline repairs.

@mergify

mergify Bot commented Sep 30, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @Duang777.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Sep 30, 2026
Signed-off-by: Lihua <1017343802@qq.com>
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
Signed-off-by: Lihua <1017343802@qq.com>
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (maintainer review of an author-owned PR)

Reviewed exact head 9f02983380fb10c2f4802f76c5b181b2f4de4b09
(rebase of fbd56efe262e75d6dc0ac3f00224addf58ea6d7f onto
main@955a91158d3b27326134f6c63793a42167a37dac).

动机

这个 PR 的目标是把三个被 main 变更打穿的测试观察点修回当前运行语义。rebase 到当前 main
后,其中两处已被 main 自身修好:generated twin 计数改成泛化的 generated >= 1 加守恒式,
turn_start_capability_hook_dispatch 也已从"其余字段等值比较"中排除并有了
kind/command/ordering/budget 断言。因此本 PR 合并后的剩余价值是两块真实加固:
hook dispatch 的身份与投影一致性(哪个 hook 产生了这次读取、投影是否逐字段保真),
以及 Host 子进程 marker 的原子发布(托管执行返回后"子进程是否仍在改状态"这一判据不再被
半写文件污染)。两者都守真实边界,不是一次性脚手架。

改动思路

rebase 时按语义解冲突而不是按文本,并且不为了保住原 diff 而回退 main 的改进:

  • generated 计数保留 main 的泛化断言,不重新引入易碎的 == 2(这正是该断言此前被打破的原因);
  • hook 断言取两者并集:main 的逐字段检查 + 本 PR 的 hook_id/capability_id 身份与
    "投影与读取逐字段一致"检查;
  • Host marker 先写 marker.next 再 renameSync 发布,读取方永远只看到完整的一次 tick。

具体改动

  • tests/control_plane/test_prompt_upgrade_hook.py(+11/−2):baseline 无 dispatch;pending 的
    dispatch 恰有一条 read,且 kind/command/ordering/prompt_budget_bytes 与公开 hint 一致;
    新增 hook_id == heartbeat.prompt_upgrade、capability_id == automation-prompt-upgrade,以及
    {key: read[key] for key in hint} == hint(投影不得丢字段或改值)。
  • tests/control_plane_ts/host_process.test.ts(+5/−3):fixture 的 counter 改为 staged 写入后原子
    rename 发布。
  • tests/architecture/test_turn_contract_generation.py:rebase 后落在 main 的版本上,该文件已不再
    出现在本 PR 的 diff 中(main 的泛化断言覆盖了同样的意图)。

对主干的风险

  • 只有测试夹具与断言,没有生产代码、公共 API、持久状态或权限变化;风险面是"这些守卫是否仍真的
    能失败"。
  • 原子 rename 不削弱 oracle:仍然要求托管执行返回后 marker 内容不再变化;它去掉的只是"先读到被截断
    的中间值、随后读到完整值"这一假阳性窗口。
  • 已验证:pytest tests/architecture/test_turn_contract_generation.py tests/control_plane/test_prompt_upgrade_hook.py 38 passed;Node 22 下
    tests/control_plane_ts/host_process.test.ts 9 passed,连续 6 次全绿;git diff --check 干净;
    rebase 后与 main@955a91158 无冲突。
  • 未验证:本地无法复现原来的偶发失败(它依赖 kill 时机),所以"消除偶发"是机理推断加重复运行观察,
    不是复现—修复的证据链;合并前的 execution-chip hairline 红项是 base 上的既有失败,与本改动无关。
  • 非阻塞建议(P2):Python 侧 tests/control_plane/test_host_process.py 使用同样的非原子
    write_text + 两次 read_text 比较(第 110/112、144/146 行),存在同一类撕裂读假阳性;
    建议后续把手写 marker 也改成 staged+rename,或抽一个共享的 marker helper,而不是让两种写法长期并存。

我的整体评价

合并后 PR 更小,但仍是真加固:不改变运行时行为,只让守卫更准、更稳。没有阻塞性发现,APPROVE。
rebase 与冲突解决已在 PR 评论中说明:generated 断言取 main 的泛化版,hook 断言取两者并集。

English verdict: APPROVE. Exact head 9f02983380fb10c2f4802f76c5b181b2f4de4b09 keeps the two
surviving test-hardening deltas after the rebase: the turn-start hook dispatch identity and
projection fidelity assertions, and the atomic Host descendant marker. Focused pytest (38
passed), the Node host-process suite (9 passed, six consecutive runs), and diff hygiene pass;
the rebase dropped the generated-pair hunk because main already generalized that guard. No
blocking findings; the only note is a non-blocking follow-up to mirror the atomic marker in the
Python host-process counterpart, which still has the same torn-read window.

@huangruiteng

Copy link
Copy Markdown
Collaborator

已按你的要求 rebase 到当前 main@955a91158 并推送,新 head 9f0298338(--force-with-lease,两个提交的原始作者与 DCO 签名保留)。

rebase 时的两处冲突按语义解决,没有为了保住原 diff 而回退 main 的改进:

  1. tests/architecture/test_turn_contract_generation.py:main 已经把该断言改成泛化的 generated >= 1 + raw == maintained + generated(这正是"计数写死"再次被打破后的修法)。因此这次不再重新引入 generated == 2,该文件已从本 PR 的 diff 中退出。保留 main 版本仍能证明"新增 authored twin 会消耗独立模块预算",语义没有变弱。
  2. tests/control_plane/test_prompt_upgrade_hook.py:main 已有 kind/command/ordering/prompt_budget_bytes 的逐字段断言与排除集合。这里取两者并集——保留 main 的逐字段检查,再加上本 PR 的 hook_id == heartbeat.prompt_upgrade、capability_id == automation-prompt-upgrade 与 {key: read[key] for key in hint} == hint(投影不得丢字段或改值)。

剩余 diff 是 2 个文件(+16/−5):上述 hook 断言,以及 tests/control_plane_ts/host_process.test.ts 里 counter 的 staged 写入 + 原子 rename 发布。

验证(新 head):pytest tests/architecture/test_turn_contract_generation.py tests/control_plane/test_prompt_upgrade_hook.py 38 passed;Node 22.22.3 下 tests/control_plane_ts/host_process.test.ts 9 passed,连续 6 次全绿;git diff --check 干净;与 main 无冲突。

评审结论:精确 head 9f0298338 已发布 APPROVE。唯一非阻塞建议(P2):Python 侧 tests/control_plane/test_host_process.py 仍用非原子 write_text + 两次 read_text 比较,存在同一类撕裂读假阳性,后续可同样改成 staged+rename 或抽一个共享 marker helper。

@huangruiteng
huangruiteng merged commit 3b73108 into loopx-project:main Sep 30, 2026
6 of 25 checks passed
@Duang777

Copy link
Copy Markdown
Collaborator Author

Follow-up PR #5365 addresses the post-merge Python marker observation with a deterministic red/green regression. It converts both test_host_process.py marker loops and the additional Codex CLI descendant marker to staged sibling writes plus os.replace, backed by a shared fixture. The change was reviewed before commit; no merge action was taken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-rebase Mergify: the pull request has merge conflicts with its base branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants